package com.zhongwang.mms.module.material.service;

import com.zhongwang.mms.gen.entity.MInventory;
import com.zhongwang.mms.gen.entity.MInventoryExample;
import com.zhongwang.mms.gen.entity.MOrderDetail;
import com.zhongwang.mms.module.material.dao.MInventoryDao;
import com.zhongwang.mms.util.BigDecimalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description: 原料在库 服务层
 * @Author: China.wsg
 * @Date: 2020/04/02 09:43
 */
@Service
public class MInventoryService {

    @Autowired
    private MInventoryDao mInventoryDao;

    /**
     * 库存在库入库方法(通用)
     *
     * @param inventory
     * @param priceFlg  单价运算机制 1:加权平均 2:不做运算
     * @return
     */
    public MInventory addInventory(MInventory inventory, Integer priceFlg) {


        MInventory mInventory = findMInventoryByQuery(inventory);

        // 如果根据批次字段在库存明细表没查出在库信息 则执行插入 否则 执行更新
        if (mInventory == null) {

            // 执行插入操作
            mInventoryDao.insert(inventory);
        } else {

            if (priceFlg == 1) {
                // 执行更新操作
                // 单价 需要加权平均（保留3位小数 金额 = 重量（kg） * 单价）
                double inStockAmountMoney = BigDecimalUtils.mul(mInventory.getItyPrice(), mInventory.getItyWeight());    // 在库总金额
                double receiveAmountMoney =  BigDecimalUtils.mul(inventory.getItyPrice(), inventory.getItyWeight());    // 接收总金额

                double allMoney = BigDecimalUtils.add(inStockAmountMoney, receiveAmountMoney);// 总金额
                double allWeight = BigDecimalUtils.add(inventory.getItyWeight(), mInventory.getItyWeight());    // 总重量


                try {
                    double newPrice =  BigDecimalUtils.div(allMoney, allWeight, 3);

                    mInventory.setItyPrice(newPrice);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            //20211126科长让新增退料反库逻辑，验证录入的单价是否为空与不同取值。
            if(priceFlg == 2){
                if (inventory.getItyPrice() == 0.00 || "".equals(inventory.getItyPrice()) || inventory.getItyPrice() == null) {
                    mInventory.getItyPrice();
                } else {
                    mInventory.setItyPrice(inventory.getItyPrice());
                }
            }
            if(inventory.getItyNum() == null) {
                inventory.setItyNum(0d);
            }
            mInventory.setItyNum(BigDecimalUtils.add(inventory.getItyNum(), mInventory.getItyNum()));
            if(inventory.getItyAvaNum()==null){
                inventory.setItyAvaNum(0d);
            }
            mInventory.setItyAvaNum(BigDecimalUtils.add(inventory.getItyAvaNum(), mInventory.getItyAvaNum()));
            if(inventory.getItyWeight()==null){
                inventory.setItyWeight(0d);
            }
            mInventory.setItyWeight(BigDecimalUtils.add(inventory.getItyWeight(), mInventory.getItyWeight()));
            if(inventory.getItyAvaWeight()==null){
                inventory.setItyAvaWeight(0d);
            }
            mInventory.setItyAvaWeight(BigDecimalUtils.add(inventory.getItyAvaWeight(), mInventory.getItyAvaWeight()));

            inventory = mInventory;
            mInventoryDao.updateByPrimaryKey(inventory);
        }
        return inventory;
    }

    /**
     * 库存在库出库方法（通用）
     *
     * @param inventory 待改库存记录
     * @param outNum    出库数量
     * @param outWeight 出库重量
     * @param avaNum    减少可用数量
     * @param avaWeight 减少可用重量
     * @return
     */
    public int subInventory(MInventory inventory, Double outNum, Double outWeight, Double avaNum, Double avaWeight) {

        inventory.setItyNum(BigDecimalUtils.sub(inventory.getItyNum(), outNum));
        inventory.setItyWeight(BigDecimalUtils.sub(inventory.getItyWeight(), outWeight));
        inventory.setItyAvaNum(BigDecimalUtils.sub(inventory.getItyAvaNum(), avaNum));
        inventory.setItyAvaWeight(BigDecimalUtils.sub(inventory.getItyAvaWeight(), avaWeight));
        return mInventoryDao.updateByPrimaryKey(inventory);
    }

    /**
     * 红冲入库明细库存执行方法
     *
     * @param inventory   现库存记录
     * @param orderDetail 单据明细
     * @return
     */
    public int redInOrderDetail(MInventory inventory, MOrderDetail orderDetail) {

        // 单价 需要加权平均（保留3位小数 金额 = 重量（kg） * 单价）
        double residueAmountMoney = BigDecimalUtils.sub(BigDecimalUtils.mul(inventory.getItyWeight(), inventory.getItyPrice()), orderDetail.getOdaAmount()); // 剩余在库金额
        double residueWeight = BigDecimalUtils.sub(inventory.getItyWeight(), orderDetail.getOdaWeight()); // 剩余在库重量
        try {
            if (residueWeight == 0) {
                inventory.setItyPrice(0.0);
            } else {
                double newPrice = BigDecimalUtils.div(residueAmountMoney, residueWeight, 3); // 单价 = 剩余在库金额 / 剩余在库数量（保留3位小数）
                inventory.setItyPrice(newPrice);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        // 库存减少
        inventory.setItyNum(BigDecimalUtils.sub(inventory.getItyNum(), orderDetail.getOdaNum()));
        inventory.setItyWeight(BigDecimalUtils.sub(inventory.getItyWeight(), orderDetail.getOdaWeight()));
        inventory.setItyAvaNum(BigDecimalUtils.sub(inventory.getItyAvaNum(), orderDetail.getOdaNum()));
        inventory.setItyAvaWeight(BigDecimalUtils.sub(inventory.getItyAvaWeight(), orderDetail.getOdaWeight()));
        return mInventoryDao.updateByPrimaryKey(inventory);
    }

    /**
     * 红冲出库明细库存执行方法
     *
     * @param inventory   现库存记录
     * @param orderDetail 单据明细
     * @return
     */
    public int redOutOrderDetail(MInventory inventory, MOrderDetail orderDetail) {

        // 单价 需要加权平均（保留3位小数 金额 = 重量（kg） * 单价）
        double inStockAmountMoney = BigDecimalUtils.mul(inventory.getItyPrice(), inventory.getItyWeight());    // 库存总金额
        double allMoney = BigDecimalUtils.add(inStockAmountMoney, orderDetail.getOdaAmount());      // 总金额
        double allWeight = BigDecimalUtils.add(inventory.getItyWeight(), orderDetail.getOdaWeight());    // 总重量
        try {
            if (allWeight == 0) {
                inventory.setItyPrice(0.0);
            } else {
                double newPrice = BigDecimalUtils.div(allMoney, allWeight, 3);
                inventory.setItyPrice(newPrice);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        // 库存增加
        inventory.setItyNum(BigDecimalUtils.add(inventory.getItyNum(), orderDetail.getOdaNum()));
        inventory.setItyWeight(BigDecimalUtils.add(inventory.getItyWeight(), orderDetail.getOdaWeight()));
        inventory.setItyAvaNum(BigDecimalUtils.add(inventory.getItyAvaNum(), orderDetail.getOdaNum()));
        inventory.setItyAvaWeight(BigDecimalUtils.add(inventory.getItyAvaWeight(), orderDetail.getOdaWeight()));
        return mInventoryDao.updateByPrimaryKey(inventory);
    }

    /**
     * 取得原料在库信息
     *
     * @param mInventory 检索条件
     * @return
     */
    public MInventory findMInventoryByQuery(MInventory mInventory) {

        MInventory mInventoryResult = null;

        MInventoryExample ex = new MInventoryExample();
        MInventoryExample.Criteria criteria = ex.createCriteria();
        criteria.andItyMatIdEqualTo(mInventory.getItyMatId());  // 原料基础表外键
        criteria.andItyTrackCodeEqualTo(mInventory.getItyTrackCode());  // 跟踪号
        criteria.andItyProCodeEqualTo(mInventory.getItyProCode());  // 项目编号
        criteria.andItyProNameEqualTo(mInventory.getItyProName());  // 项目名称
        criteria.andItySpecEqualTo(mInventory.getItySpec());  // 特殊说明
        criteria.andItyInTypeEqualTo(mInventory.getItyInType());  // 在库类型
        criteria.andItyStoIdEqualTo(mInventory.getItyStoId());  // 仓库
        if (mInventory.getSupplier()!=null){
            criteria.andSupplierTo(mInventory.getSupplier());
        }else   {
            criteria.andSupplierTo("");
        }

        /*if(mInventory.getItyPosition()!=null){
            criteria.andItyPositionEqualTo(mInventory.getItyPosition());//区位
        }*/

        List<MInventory> mInventories = mInventoryDao.selectByExample(ex);

        if (mInventories != null && mInventories.size() > 0) {
            mInventoryResult = mInventories.get(0);
        }

        return mInventoryResult;
    }


}
